package com.kingdee.eas.custom.hr.assessment.specialbonus.app;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import antlr.StringUtils;
import bsh.StringUtil;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.metadata.entity.EntityViewInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.metadata.entity.FilterItemInfo;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.basedata.mm.qm.utils.DateUtils;
import com.kingdee.eas.basedata.org.AdminOrgUnitInfo;
import com.kingdee.eas.basedata.org.HROrgUnitInfo;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.custom.hr.assessment.base.AssessmentLevelInfo;
import com.kingdee.eas.custom.hr.assessment.base.AssessmentTimeConfigInfo;
import com.kingdee.eas.custom.hr.assessment.specialbonus.ApplyDateEnum;
import com.kingdee.eas.custom.hr.assessment.specialbonus.ThreeLevelSpecialCollection;
import com.kingdee.eas.custom.hr.assessment.specialbonus.ThreeLevelSpecialEntryInfo;
import com.kingdee.eas.custom.hr.assessment.specialbonus.ThreeLevelSpecialFactory;
import com.kingdee.eas.custom.hr.assessment.specialbonus.ThreeLevelSpecialInfo;
import com.kingdee.eas.framework.CoreBaseCollection;
import com.kingdee.eas.hr.base.ApproveTypeEnum;
import com.kingdee.eas.hr.base.HRBillStateEnum;
import com.kingdee.eas.hr.canon.cbase.GradeInfo;
import com.kingdee.eas.hr.compensation.util.HRSchemeUtils;
import com.kingdee.eas.hr.rec.util.DateUtil;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;

public class ThreeLevelSpecialFacadeControllerBean extends
		AbstractThreeLevelSpecialFacadeControllerBean {
	private static Logger logger = Logger
			.getLogger("com.kingdee.eas.custom.hr.assessment.specialbonus.app.ThreeLevelSpecialFacadeControllerBean");

	protected void _getExecute(Context ctx) throws BOSException {

		Date sysDate = new Date();
		String current = DateUtil.format(sysDate, "yyyy-MM-dd");
		StringBuffer sql = new StringBuffer();
		sql.append("/*dialect*/select fid,fnumber,fbegindate,fenddate ")
				.append(" from T_BAS_ASSESSMENTTIMECONFIG").append(
						" where to_char(fbegindate,'YYYY-MM-DD')<='" + current
								+ "' and to_char(fenddate,'YYYY-MM-DD')>='"
								+ current + "'");
		//--By YB20121214 START
		Calendar c = Calendar.getInstance();
		//c.add(Calendar.MONTH, -6);
		//String current6month = DateUtil.format(c.getTime(), "yyyy-MM-dd");
		String year = String.valueOf(c.get(Calendar.YEAR));
		String month = String.valueOf(sysDate.getMonth() + 1);
		if(month.length()<2){
			month = "0"+month;
		}
		//--By YB20121214 END
		
		IRowSet rs = DbUtil.executeQuery(ctx, sql.toString());

		StringBuffer buffer = new StringBuffer();
		buffer.append("	/*dialect*/					\n");
		buffer.append("	SELECT distinct T1.FID          AS PERSON_ID,					\n");
		buffer.append("	       T1.FNUMBER      AS PERSON_NUMBER,					\n");
		buffer.append("	       T1.FNAME_L2     AS PERSON_NAME,					\n");
		buffer.append("	       T1.FJOINJOBDATE AS PERSON_ENTERDATE,					\n");

		buffer.append("	       T2.FID          AS ADMINORGUNIT_ID,					\n");
		buffer.append("	       T2.FNUMBER      AS ADMINORGUNIT_NUMBER,					\n");
		buffer.append("	       T2.FNAME_L2     AS ADMINORGUNIT_NAME,					\n");
		buffer.append("	       T3.FID          AS ATTENDANCECODE_ID,					\n");
		buffer
				.append("	       T3.FNUMBER      AS ATTENDANCECODE_NUMBER,					\n");
		buffer.append("	       T3.FNAME_L2     AS ATTENDANCECODE_NAME,					\n");
		buffer.append("	       T4.FID          AS ADMINORGBASE_ID,					\n");
		buffer.append("	       T4.FNUMBER      AS ADMINORGBASE_NUMBER,					\n");
		buffer.append("	       T4.FNAME_L2     AS ADMINORGBASE_NAME,					\n");
		buffer.append("	       T5.FID          AS GRADE_ID,					\n");
		buffer.append("	       T5.FNUMBER      AS GRADE_NUMBER,					\n");
		buffer.append("	       T5.FNAME_L2     AS GRADE_NAME,					\n");
		buffer.append("	       T5.CFLEVEL      AS GRADE_LEVEL,					\n");
		//--By YB20121214 START
		buffer.append("	        nvl(T10.FENDDATE,T11.FENDDATE)   AS ENDDATE,   	\n");
		//--END
		buffer.append("	       T9.FID      AS BEFASSESSMENTLEVEL			\n");
		buffer.append("	  FROM T_BD_PERSON T1					\n");
		buffer.append("	 LEFT JOIN T_ORG_ADMIN T2					\n");
		buffer.append("	    ON T1.CFDEPTID = T2.FID					\n");
		buffer.append("	 LEFT JOIN CT_BAS_ATTENDANCECODE T3					\n");
		buffer.append("	    ON T1.FATTENDANCECODEID = T3.FID					\n");
		buffer.append("	 INNER JOIN T_CAN_ADMINORGBASE T4					\n");
		buffer.append("	    ON T1.FADMINORGBASEID = T4.FID					\n");
		buffer.append("	 INNER JOIN T_CAN_GRADE T5					\n");
		buffer.append("	    ON T1.FGRADEID = T5.FID					\n");
		buffer.append("	 INNER JOIN T_HR_EMPLOYEECLASSIFY T6					\n");
		buffer.append("	    ON T1.FEMPLOYEECLASSIFYID = T6.FID					\n");
		buffer
				.append("	   AND (T6.FLONGNUMBER LIKE '1%' OR T6.FLONGNUMBER LIKE '0%')					\n");
		buffer
				.append("	  LEFT JOIN (SELECT A.CFPERNUMBERID    AS PERSON_ID,					\n");
		buffer
				.append("	                    A.CFLASTEVALUATION AS LASTEVALUATION					\n");
		buffer
				.append("	               FROM CT_SPE_THREELEVELSPECIALENTRY A					\n");
		buffer
				.append("	               LEFT JOIN CT_SPE_THREELEVELSPECIAL B					\n");
		buffer.append("	                 ON A.FBILLID = B.FID					\n");
		buffer
				.append("	              WHERE B.FNUMBER IN (SELECT MAX(B.FNUMBER)					\n");
		buffer
				.append("	                                    FROM CT_SPE_THREELEVELSPECIALENTRY A					\n");
		buffer
				.append("	                                    LEFT JOIN CT_SPE_THREELEVELSPECIAL B					\n");
		buffer
				.append("	                                      ON A.FBILLID = B.FID					\n");
		buffer
				.append("	                                   WHERE B.FBILLSTATE = 3					\n");
		buffer
				.append("	                                   GROUP BY A.CFPERNUMBERID)) T8					\n");
		buffer.append("	    ON T1.FID = T8.PERSON_ID					\n");

		buffer.append("	    LEFT JOIN T_BAS_ASSESSMENTLEVEL T9								\n");
		buffer.append("	    	ON T8.LASTEVALUATION = T9.FID								\n");
		//--By YB20121214 START
		buffer.append("		LEFT JOIN (SELECT A1.FPERSONID,                                  \n"); 
		buffer.append("						  A1.FENDDATE                                     \n");
		buffer.append("					FROM T_HR_PERSONWORKEXPCUR A1                         \n");
		buffer.append("						LEFT JOIN T_CAN_ADMINORGBASE A2                   \n");
		buffer.append("						ON A1.FCOSTCENTERID = A2.FID                      \n");
		buffer.append("					WHERE A2.FNUMBER = '2590'                             \n");  
		if(("06").equals(month)){
			buffer.append("							AND ((TO_CHAR(A1.FBEGINDATE, 'YYYY-MM-DD') BETWEEN '" + year + "-01-01' AND \n");
			buffer.append("							'" + year + "-06-30') OR (TO_CHAR(A1.FENDDATE, 'YYYY-MM-DD') BETWEEN        \n");
			buffer.append("							'" + year + "-01-01' AND '" + year + "-06-30'))                \n");
			
		}else if(("12").equals(month)){
			buffer.append("							AND ((TO_CHAR(A1.FBEGINDATE, 'YYYY-MM-DD') BETWEEN '" + year + "-07-01' AND \n");
			buffer.append("							'" + year + "-12-31' ) OR (TO_CHAR(A1.FENDDATE, 'YYYY-MM-DD') BETWEEN        \n");
			buffer.append("							'" + year + "-07-01' AND '" + year + "-12-31' ))                \n");
		}
		buffer.append("                                                                    )T10\n");
		buffer.append("	    ON T1.FID = T10.FPERSONID						\n");
		
		
		buffer.append("		LEFT JOIN (SELECT A1.FPERSONID,                                  \n"); 
		buffer.append("						  A1.FENDDATE                                     \n");
		buffer.append("					FROM T_HR_PERSONWORKEXPCUR A1                         \n");
		buffer.append("						LEFT JOIN T_CAN_ADMINORGBASE A2                   \n");
		buffer.append("						ON A1.FOLDCOSTCENTERID = A2.FID                      \n");
		buffer.append("					WHERE A2.FNUMBER = '2590'                             \n");  
		if(("06").equals(month)){
			buffer.append("							AND ((TO_CHAR(A1.FBEGINDATE, 'YYYY-MM-DD') BETWEEN '" + year + "-01-01' AND \n");
			buffer.append("							'" + year + "-06-30') OR (TO_CHAR(A1.FENDDATE, 'YYYY-MM-DD') BETWEEN        \n");
			buffer.append("							'" + year + "-01-01' AND '" + year + "-06-30'))                \n");
			
		}else if(("12").equals(month)){
			buffer.append("							AND ((TO_CHAR(A1.FBEGINDATE, 'YYYY-MM-DD') BETWEEN '" + year + "-07-01' AND \n");
			buffer.append("							'" + year + "-12-31' ) OR (TO_CHAR(A1.FENDDATE, 'YYYY-MM-DD') BETWEEN        \n");
			buffer.append("							'" + year + "-07-01' AND '" + year + "-12-31' ))                \n");
		}
		buffer.append("                                                                    )T11\n");
		buffer.append("	    ON T1.FID = T11.FPERSONID						\n");
		
		
		//--END
		buffer
				.append("	 WHERE T1.FEMPLOYEETYPEID != '00000000-0000-0000-0000-0000000000035C14FC3A'					\n");

		buffer
				.append("	 AND T1.FEMPLOYEECLASSIFYID !='fzDos/Y5RrqIXVUK1qsbttFr7H0='	\n");
		buffer.append("	 AND T5.CFLEVEL = 3					\n");
		System.out.println("SQL:" + buffer.toString());

		AssessmentTimeConfigInfo assTimeConfig = new AssessmentTimeConfigInfo();
		try {
			if (rs.next()) {
				assTimeConfig.setId(BOSUuid.read(rs.getString("fid")));
				assTimeConfig.setNumber(rs.getString("fnumber"));
				assTimeConfig.setBeginDate(rs.getDate("fbegindate"));
				assTimeConfig.setEndDate(rs.getDate("fenddate"));
			} else {
				return;
			}

			rs = DbUtil.executeQuery(ctx, buffer.toString());

			List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();

			ThreeLevelSpecialInfo bill = null;

			Set<String> billNums = new HashSet<String>();

			HROrgUnitInfo hro = HRSchemeUtils.getServerHROrgUnitInfo(ctx);

			while (rs.next()) {
				String person_id = rs.getString("PERSON_ID");
				String person_number = rs.getString("PERSON_NUMBER");
				String person_name = rs.getString("PERSON_NAME");
				Date person_enterdate = rs.getDate("PERSON_ENTERDATE");
				String adminorgunit_id = rs.getString("ADMINORGUNIT_ID");
				String adminorgunit_number = rs
						.getString("ADMINORGUNIT_NUMBER");
				String adminorgunit_name = rs.getString("ADMINORGUNIT_NAME");
				String attendancecode_id = rs.getString("ATTENDANCECODE_ID");
				String attendancecode_number = rs
						.getString("ATTENDANCECODE_NUMBER");
				String attendancecode_name = rs
						.getString("ATTENDANCECODE_NAME");
				String adminorgbase_id = rs.getString("ADMINORGBASE_ID");
				String adminorgbase_number = rs
						.getString("ADMINORGBASE_NUMBER");
				String adminorgbase_name = rs.getString("ADMINORGBASE_NAME");
				String grade_id = rs.getString("GRADE_ID");
				String grade_number = rs.getString("GRADE_NUMBER");
				String grade_name = rs.getString("GRADE_NAME");
				String grade_level = rs.getString("GRADE_LEVEL");
				String befassessmentlevel = rs.getString("BEFASSESSMENTLEVEL");
				//--By YB20121214 START
				Date maternityDate = rs.getDate("ENDDATE");
				//--By YB20121214 END
				Map<String, Object> map = new HashMap<String, Object>();

				map.put("PERSON_ID", person_id);
				map.put("PERSON_NUMBER", person_number);
				map.put("PERSON_NAME", person_name);
				map.put("PERSON_ENTERDATE", person_enterdate);
				map.put("ADMINORGUNIT_ID", adminorgunit_id);
				map.put("ADMINORGUNIT_NUMBER", adminorgunit_number);
				map.put("ADMINORGUNIT_NAME", adminorgunit_name);
				map.put("ATTENDANCECODE_ID", attendancecode_id);
				map.put("ATTENDANCECODE_NUMBER", attendancecode_number);
				map.put("ATTENDANCECODE_NAME", attendancecode_name);
				map.put("ADMINORGBASE_ID", adminorgbase_id);
				map.put("ADMINORGBASE_NUMBER", adminorgbase_number);
				map.put("ADMINORGBASE_NAME", adminorgbase_name);
				map.put("GRADE_ID", grade_id);
				map.put("GRADE_NUMBER", grade_number);
				map.put("GRADE_NAME", grade_name);
				map.put("GRADE_LEVEL", grade_level);
				map.put("BEFASSESSMENTLEVEL", befassessmentlevel);
				map.put("HRO", hro);
				//--By YB20121214 START
				map.put("MATERNITYDATE", maternityDate);
				//--By YB20121214 END
				billNums.add(assTimeConfig.getNumber() + "-"
						+ adminorgunit_number);

				datas.add(map);
			}
			Map<String, ThreeLevelSpecialInfo> bills = this
					.getThreeLevelSpecialBill(ctx, billNums);

			Iterator<Map<String, Object>> dit = datas.iterator();
			Map<String, Object> m = null;
			while (dit.hasNext()) {

				m = dit.next();

				String deptNum = (String) m.get("ADMINORGUNIT_NUMBER");
				String billNum = assTimeConfig.getNumber() + "-" + deptNum;
				if (bills.containsKey(billNum)) {
					bill = bills.get(billNum);
				} else {
					bill = this.createBill(m, assTimeConfig);
					bills.put(billNum, bill);
				}

				bill.getEntrys().add(this.createEntry(m));
			}

			Set<Entry<String, ThreeLevelSpecialInfo>> set = bills.entrySet();
			Iterator<Entry<String, ThreeLevelSpecialInfo>> it = set.iterator();

			CoreBaseCollection collection = new CoreBaseCollection();
			while (it.hasNext()) {
				collection.add(it.next().getValue());
			}
			ThreeLevelSpecialFactory.getLocalInstance(ctx).saveBatchData(
					collection);

		} catch (Exception e) {
			e.printStackTrace();
			throw new BOSException(e);
		}

	}

	private Map<String, ThreeLevelSpecialInfo> getThreeLevelSpecialBill(
			Context ctx, Set<String> numbers) throws BOSException {

		FilterInfo fi = new FilterInfo();
		fi.getFilterItems().add(
				new FilterItemInfo("number", numbers, CompareType.INCLUDE));

		EntityViewInfo view = new EntityViewInfo();
		view.getSelector().add("id");
		view.getSelector().add("number");
		view.setFilter(fi);

		ThreeLevelSpecialCollection collection = ThreeLevelSpecialFactory
				.getLocalInstance(ctx).getThreeLevelSpecialCollection(view);

		ThreeLevelSpecialInfo info = null;
		Map<String, ThreeLevelSpecialInfo> bills = new HashMap<String, ThreeLevelSpecialInfo>();
		for (int i = 0; i < collection.size(); i++) {
			info = collection.get(i);
			bills.put(info.getNumber(), info);
		}
		return bills;

	}

	private ThreeLevelSpecialInfo createBill(Map<String, Object> m,
			AssessmentTimeConfigInfo info) throws Exception {

		int year = Calendar.getInstance().get(Calendar.YEAR);
		int month = Calendar.getInstance().get(Calendar.MONTH) + 1;

		ApplyDateEnum applyDateEnum = month > 6 ? ApplyDateEnum.allYear
				: ApplyDateEnum.beforeYear;

		ThreeLevelSpecialInfo bill = new ThreeLevelSpecialInfo();

		String deptNum = (String) m.get("ADMINORGUNIT_NUMBER");
		String deptId = (String) m.get("ADMINORGUNIT_ID");

		HROrgUnitInfo hro = (HROrgUnitInfo) m.get("HRO");
		bill.setNumber(info.getNumber() + "-" + deptNum);
		if (deptId != null) {
			AdminOrgUnitInfo d = new AdminOrgUnitInfo();
			d.setId(BOSUuid.read(deptId));
			bill.setAdminOrg(d);
		}
		bill.setHrOrgUnit(hro);
		bill.setApplyDate(DateUtil.getCurrentDate());
		bill.setBillState(HRBillStateEnum.SAVED);
		bill.setApproveType(ApproveTypeEnum.WORKFLOW);
		bill.setApplyDateTime(applyDateEnum);
		bill.setApplyYear(String.valueOf(year));

		return bill;
	}

	private ThreeLevelSpecialEntryInfo createEntry(Map<String, Object> m)
			throws Exception {

		ThreeLevelSpecialEntryInfo entry = new ThreeLevelSpecialEntryInfo();

		String person_id = (String) m.get("PERSON_ID");
		String person_number = (String) m.get("PERSON_NUMBER");
		String person_name = (String) m.get("PERSON_NAME");
		Date person_enterdate = (Date) m.get("PERSON_ENTERDATE");
		String adminorgunit_id = (String) m.get("ADMINORGUNIT_ID");
		String adminorgunit_number = (String) m.get("ADMINORGUNIT_NUMBER");
		String adminorgunit_name = (String) m.get("ADMINORGUNIT_NAME");
		String attendancecode_id = (String) m.get("ATTENDANCECODE_ID");
		String attendancecode_number = (String) m.get("ATTENDANCECODE_NUMBER");
		String attendancecode_name = (String) m.get("ATTENDANCECODE_NAME");
		String adminorgbase_id = (String) m.get("ADMINORGBASE_ID");
		String adminorgbase_number = (String) m.get("ADMINORGBASE_NUMBER");
		String adminorgbase_name = (String) m.get("ADMINORGBASE_NAME");
		String grade_id = (String) m.get("GRADE_ID");
		String grade_number = (String) m.get("GRADE_NUMBER");
		String grade_name = (String) m.get("GRADE_NAME");
		String grade_level = (String) m.get("GRADE_LEVEL");
		String befassessmentlevel = (String) m.get("BEFASSESSMENTLEVEL");
		//--By YB20121214 START
		Date maternitydate = (Date)m.get("MATERNITYDATE");
		//--By YB20121214 END
		if (person_id != null) {
			PersonInfo p = new PersonInfo();
			p.setId(BOSUuid.read(person_id));
			entry.setPerNumber(p);
		}

		entry.setOrgUnit(adminorgunit_name);

		entry.setCostOrg(adminorgbase_name);
		entry.setGroundIdleCode(attendancecode_name);
		//--By YB20121214 START
		if(maternitydate != null){
			entry.setMaternityDate(maternitydate);
		}
		//--By YB20121214 END
		if (grade_id != null) {
			GradeInfo g = new GradeInfo();
			g.setId(BOSUuid.read(grade_id));
			entry.setLevelNumber(g);
			entry.setLevel(grade_level);
		}

		entry.setEntranceDate(person_enterdate);

		if (befassessmentlevel != null) {
			AssessmentLevelInfo assessmentLevel = new AssessmentLevelInfo();
			assessmentLevel.setId(BOSUuid.read(befassessmentlevel));
			entry.setBefAssessmentLevel(assessmentLevel);
		}

		return entry;
	}
}